package concurrency.basicthreading.demo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 
 * Java SE5 java.util.concurrent 中提供了Executor来管理Thread对象。
 *
 * ExecutorService 对象是使用Executors的静态方法创建的。这个方法决定了Executor的类型. ExecutorServiced对象知道如何执行Runnable对象。
 * 
 * Executor 分为三种类型：CacheThreadPool、 FixedThreadPool、  SingleThreadExecutor
 * 
 * CacheThreadPool：将为每个任务分配一个线程，(线程数量不固定)
 * FixedThreadPool：在初始化时必须确定线程数量。一次性的执行代价高昂的线程分配。(线程数量是固定)
 * SingleThreadExecutor：就是线程数量为1的FixedThreadPool。
 * 
 * 注意：任何线程池中，现有的线程在可能的情况下，都会被自动的复用。(CacheThreadPool在就得线程回收时不创建新线程)。
 * 
 * Executor是 Java SE5/6 中启动任务的优选方法：
 * 	1.	start()方法在构造函数中调用的。在构造函数中启动线程是很危险的。
 * 		因为一个任务可能会在构造器结束之前开始执行。这意味着该任务能够访问处于不稳定状态的对象。
 * 		这是为什么优选Executor创建线程的原因之一。
 * 
 *  2.Executor 控制的所有任务可用同时被关闭 P1135。
 */
public class Demo03Executor {
	public static void main(String[] args) {
		//CacheThreadPool
		ExecutorService exec = Executors.newCachedThreadPool();
		
		for (int i = 0; i < 20; i++) {
			exec.execute(new Demo01Runnable());
		}
		//shutdown方法用于防止新的任务被提交到Executor(线程池)，当shutdown方法调用之后，shutdown方法调用之前提交的所有任务将继续执行。
		exec.shutdown();
		
		
		//FixedThreadPool
		exec = Executors.newFixedThreadPool(5);
		for (int i = 0; i < 20; i++) {
			exec.execute(new Demo01Runnable());
		}
		exec.shutdown();
		
		//SingleThreadExecutor：当有多个任务被提交到了SingleThreadExecutor时。所有的任务将排队。每个任务会在下一任务开始前结束
		//所有任务将使用同一线程并按照提交顺序执行。
		exec = Executors.newSingleThreadExecutor();
		for (int i = 0; i < 20; i++) {
			exec.execute(new Demo01Runnable());
		}
		exec.shutdown();
		
	}
}
